package edu.maping.easy.sequence;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import com.sun.xml.internal.txw2.annotation.XmlElement;

import processing.core.PApplet;
import processing.xml.XMLElement;
import edu.maping.easy.model.Thing;
import edu.maping.easy.painter.PainterContainer;
import edu.maping.easy.painter.ThingPainterDelegate;
import edu.maping.easy.sequence.ticker.PropagationTicker;
import edu.maping.easy.sequence.ticker.Ticker;
import edu.maping.easy.sequence.ticker.TickerListener;

public class ActionEvent {

	public ActionConf actionConf = null;

	public PainterContainer painterContainer = null;

	public Ticker ticker = null;

	protected List<PropagationTicker> propagationRequired = new ArrayList<PropagationTicker>();

	public ActionEvent() {
		// TODO Auto-generated constructor stub
	}

	public void update(PApplet pApplet, Thing thing) {

		painterContainer.painterDelegate.setConf(actionConf);
		painterContainer.painterDelegate.setThing(thing);
		if (ticker == null) {
			System.out.println("ERRORRRRRRRRRRRRRRRRRRRR sabes donde estoy?");
			return;
		}

		if (painterContainer.painterDelegate instanceof TickerListener) {
			ticker.updateTrigger(pApplet, thing);
			if (ticker.isTrigerred()) {
				TickerListener tickerListener = (TickerListener) painterContainer.painterDelegate;
				tickerListener.turnOn();
				for (int index = 0; index < propagationRequired.size(); index++) {
					propagationRequired.get(index).setPropagationMoment(
							pApplet.frameCount);
				}
			}
		}

//		painterContainer.draw(thing, pApplet);

	}

	public ActionEvent copy() {
		ActionEvent actionEvent = new ActionEvent();

		actionEvent.ticker = ticker.newTicker();
		actionEvent.actionConf = actionConf.copy();
		actionEvent.painterContainer = painterContainer.createNewInstance();

		return actionEvent;

	}

	public XMLElement xmlIzation() {

		XMLElement xmlElement = new XMLElement();
		xmlElement.setName("actionEvent");
		xmlElement.setAttribute("actionConf", actionConf.toString());
		// xmlElement.setAttribute("thing", thing.getClass().toString());
		xmlElement.setAttribute("painterDelegate", painterContainer.getClass()
				.getCanonicalName());

		XMLElement tickerElement = ticker.xmlIzation();
		xmlElement.setAttribute("ticker", ticker.getClass().getCanonicalName());
		if (tickerElement != null)
			xmlElement.addChild(tickerElement);

		return xmlElement;
	}

	public ActionEvent DesXmlIzation(XMLElement father) {

		ActionEvent actionEvent = new ActionEvent();

		String stringX = father.getAttribute("actionConf");
		if (stringX != null) {
			Pattern p = Pattern.compile("[\\{\\}\\=\\, ]++");
			String[] split = p.split(stringX);
			actionEvent.actionConf = new ActionConf();
			for (int i = 1; i < split.length; i += 2) {
				float value = Float.parseFloat(split[i + 1]);
				actionEvent.actionConf.put(split[i], value);
			}
		}

		String delegateClassName = father.getAttribute("painterDelegate");
		if (delegateClassName != null) {
			Class delegateClass = null;
			try {
				delegateClass = Class.forName(delegateClassName);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}

			try {
				ThingPainterDelegate painterDelegate = (ThingPainterDelegate) delegateClass
						.newInstance();
				// actionEvent.painterContainer = painterDelegate;
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}

		String tickerClassName = father.getAttribute("ticker");
		if (tickerClassName != null) {
			Class tickerClass = null;
			try {
				tickerClass = Class.forName(tickerClassName);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}

			try {
				Ticker ticker = (Ticker) tickerClass.newInstance();
				int count = father.getChildCount();
				if (count > 0) {
					for (int i = 0; i < count; i++) {
						XMLElement tickerElement = father.getChild(i);
						if (tickerElement.getName().equals("Ticker")) {
							ticker.desXmlIzation(tickerElement);
							break;
						}
					}
				}
				actionEvent.ticker = ticker;
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}

		//
		// String stringId = father.getAttribute("id");
		// if (stringId != null)
		// id = Long.parseLong(stringId);

		return actionEvent;

	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((painterContainer == null) ? 0 : painterContainer.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {

		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ActionEvent other = (ActionEvent) obj;
		if (painterContainer == null) {
			if (other.painterContainer != null)
				return false;
		} else if (!painterContainer.painterDelegate.getName().equals(
				other.painterContainer.painterDelegate.getName()))
			return false;
		return true;
	}
}
